K Compiler ――――――――――――――――――――――――――――――――――――――― I/O 1983年10月号掲載 FM−8 Kコンパイラ ”KCMP” マシン語 $2000−$3FFF S=$2000 ランタイム  ”RUNT” マシン語 $6D00−$6FFF 起動方法 CLEAR10,&H1FFF LOADM”” LOADM”” コンパイル EXEC&H2000 オブジェクト実行 EXEC&H4000 ――――――――――――――――――――――――――――――――――――――― 拡張性豊かな6809コンパイラ ――――――――――――――― “K”はMC6809をCPUとするシステムで動かせるコンパイラです。 コンパイラは“K”で記述されたソース・プログラムを MC6809のオブジェクトに直接変換します。 “K”は本コンパイラのために命名したもので、 整数型BASICに類似していますが、 引数を使用した手続き、関数、コール、REPEAT、WHILE、 IF、THEN、ELSEなどの拡張がなされています。 生成されるオブジェクトは、6809の特徴を生かし、 位置自由(ポジション・インディペンデント)であり、 オブジェクト・プログラムが使用する ランタイム・ルーチンのハードウェアに依存する部分は、 1文字の入出力と1行入力のみであり、 コンパイルしたオブジェクトを 他のシステムで容易に動かすことができます。 =−=−=−=−=−=−=−=−=−= K Compilerの特長 =−=−=−=−=−=−=−=−=−= “K”は整数型の非構造化言語であり、 命令形式は標準BASICと同一です。 BASICと異なる点をまとめると次のようになります。 (1)文番号がない。文の区切りが、セミコロン“;”である。 (2)構造化ステートメントが拡張されている。 (3)IF文の有効範囲の指定方法が異なる。 (4)手続き(サブルーチン)に対し、引数が使える。 (5)ユーザーのサブルーチンに対し、引数が使える。 (6)配列に1バイト配列と2バイト配列がある。 (7)FOR −NEXTのNEXT文で、変数を指定できない。 (8)PRINT文 の詳細が異なる。 (9)INPUT、GETの形式が異なる。 (10)END文 がない。 =−=−=−=−=−=−=−=−=−=  BASICとの相異点 =−=−=−=−=−=−=−=−=−= (1)ラベルと文の区切り BASlCではGOTO文、GOSUB文 の飛び先を 文番号で指定しますが、 “K”には文番号の概念がなく、ラベルを使用します。 ラベルは英字で始まる英数字列で、 ラベル名のすぐ後にセミコロンを書くことでその場所に定義されます。 ・――――――――――――――――――――――・ |■■■BASIC■■■|■■■■K■■■■■| |―――――――――――+――――――――――| | 10 GOTO 20 | GOTO L20 | | 20 GOSUB 30 | L20; | | 30 RETURN | GOSUB L30 | | | L30; | | | RETURN | ・――――――――――――――――――――――・ 1行に複数の文を書く場合のセパレータが、 BASICではコロン“:”だが “K”ではセミコロン“;”を使う。 ・――――――――――――――――――――――・ |■■■BASIC■■■|■■■■K■■■■■| |―――――――――――+――――――――――| | 10 A=10:B=20 | A=10;B=20 | ・――――――――――――――――――――――・ (2)REPEAT、WHILE 標準的なBASICにはない REPEAT文、WHILE文 が使用できる。 一般形は、   ・――――――――――――――――・ | REPEAT | | 文 | | UNTIL 条件式 |   ・――――――――――――――――・   ・――――――――――――――――・ | WHILE 粂件式 | | 文 | | WEND |   ・――――――――――――――――・ です。 REPEAT文は条件が成立するまで、 WHILE は条件が成立している間、 REPEAT−UNTIL、 WHILE−WEND で囲まれている文を実行します。 コンパイラはこれらの文をスタックを使わないオブジェクトに展開します。 したがって、REPEAT節、WHILE節 への飛び込み、 飛び出しは自由に行なうことができます。 ・――――――――――――――――――――――・ |■■■K■■■|■■■展開されるコード■■■| |―――――――+――――――――――――――| |REPEAT |L01 EQU * | | I=I+1 | LDD I | |UNTILI>1000 | ADDD #1 | | | STD I ;I=I+1 | | | LDD I | | | SUBD #1000 | | | BLE L01 ; ifI<=1000 | | | then L01 | ・――――――――――――――――――――――・ ・――――――――――――――――――――――・ |■■■K■■■|■■■展開されるコード■■■| |―――――――+――――――――――――――| |WHILE I<=1000 |L01 LDD I | | I=I+1 | SUBD #1000 | |WEND | LBGT L02 | | | LDD I | | | ADDD #1 | | | STD L I | | | BRA L01 | | |L02 EQU * | ・――――――――――――――――――――――・ (3)IF文=================== BASICのIF文は1行という制約があるが、 KではIF文の有効範囲をFIで明示することにより、 THEN節、ELSE節の複数文化を許しています。 IF文のネストには制限はないが、 1つのIFに対し必らず対応するFIがなくてはなりません。 ・――――――――――――――――――――――・ |■■■BASIC■■■|■■■■K■■■■■| |―――――――――――+――――――――――| |10 IF A>B THEN 40 |IF A<=B THEN | |20 C=B:D=A |C=B;D=A | |30 GOTO 50 |ELSE | |40 C=A:D=B | C=A;D=B | |50 : |FI | |   : |: | ・――――――――――――――――――――――・ (4)GOSUB文================ GOSUB 〈ラベル〉〔引数1,引数2,…,引数n〕 という形式でサブルーチンに引数を渡せます。 ・――――――――――――――――――――――・ |■■■■■■■■■■K■■■■■■■■■■■| |――――――――――――――――――――――| |〔例〕 GOSUB ALPHA [Z,A,"ABCD"] | |――――――――――――――――――――――| | 〈展開されるコード〉 | | LDD #2 | | PUSH D | | LDD A | | PUSH D | | LEAX 1000 | | |UNTIL〈条件式〉 | | | |―――――――――――+――――――――+――――――――――――――――| |WHILE〈粂件式〉 |WHILE I<1000 |条件が成立している間ループ | | | | | | 文        |I=I+1 | | | | | | |WEND |WEND | | |――――――――――――――――――――+――――――――――――――――| |FOR〈変数〉=〈初期値〉TO〈最終値〉 |繰り返し | | 〔STEP〈きざみ値〉〕 | | | 文 | | | | | |NEXT | | |――――――――――――――――――――+――――――――――――――――| |IF〈条件式〉THEN |IF A=A'THEN |条件が成立していると文1を | | | B='B';C='C' |成立しないときは文2を実行する。| | 文1 |ELSE | | |ELSE | B='D';C='E' | | |         |FI | | | 文2 | | | | | | | |FI | | | |―――――――――――+――――――――+――――――――――――――――| |CALL〈アドレス〉 |CALL $F000 |ユーザーサブルーチン、 | | | |システム・サブルーチンのコール | |―――――――――――+――――――――+――――――――――――――――| |POKE〈アドレス〉,〈値〉 |POKE $200,B+3 |アドレスに値をストア | |PRINT 出力要素〔,…〕|PRINT"ABC",A |CRTに対するプリント・アウト | |CODE〈値〉〔,…〕 *|CODE$34,$1C,$17 |値を プログラムのこの文の位置に展開| ・―――――――――――――――――――――――――――――――――――――・                     関数 ・―――――――――――――――――――――――――――――――――――――・ |■■■一■般■形■■■|■使■用■例■■|■■■■機■■■■■■能■■■■| |―――――――――――+――――――――+――――――――――――――――| |PEEK(〈アドレス〉) |PEEK($1000) |アドレス のメモリ 内を値とする | |―――――――――――+――――――――+――――――――――――――――| |RND(〈式〉) |RNDF(100) |0〜式の値−1の一様乱数を発生 | | | |0≦RND(n)<n | |―――――――――――+――――――――+――――――――――――――――| |INPUT |        |キーボードより入力する数値を | | | |値とする | |―――――――――――+――――――――+――――――――――――――――| |GET |        |キーが押されるまで待ち、押された | |           | |キーの ASCIIコードを値とする | |―――――――――――+――――――――+――――――――――――――――| |NOT(〈式〉) |NOT(A>1) |論理否定演算 | |―――――――――――+――――――――+――――――――――――――――| |ABS(〈式〉)  |ABS(A+B) |絶対値 | |―――――――――――+――――――――+――――――――――――――――| |-〈式〉 |-100 |負数 | |―――――――――――+――――――――+――――――――――――――――| |LOW(〈式〉〉 *| |式の下位バイトを値とする | |―――――――――――+――――――――+――――――――――――――――| |HIGH(〈式〉) *| |式の上位バイトを値とする | |―――――――――――+――――――――+――――――――――――――――| |ADR(変数) *| |変数のアドレスを値とする | |―――――――――――+――――――――+――――――――――――――――| |SGN(〈式〉) *| |式の符号を値とする。 | | | |0は0を値とする。 | ・―――――――――――――――――――――――――――――――――――――・            PRINT文中で使用できる関数 ・―――――――――――――――――――――――――――――――――――――・ |■■■一■般■形■■■|■使■用■例■■|■■■■機■■■■■■能■■■■| |―――――――――――+――――――――+――――――――――――――――| |/ | |改行子 | |―――――――――――+――――――――+――――――――――――――――| |CHR$(〈式〉) |CHR$(4) |式の値を ASCIIコードとして出力 | |―――――――――――+――――――――+――――――――――――――――| |HEX$(〈式〉) |HEX$(-121) |式の値を16進4桁で出力 | |―――――――――――+――――――――+――――――――――――――――| |HEX2$(〈式〉) |HEX2$("A") |式の値を16進2桁で出力 | |―――――――――――+――――――――+――――――――――――――――| |SPC$(〈式〉) |SPC$(3) |式の値の数の スペースを出力  | |―――――――――――+――――――――+――――――――――――――――| |"〈文字列〉" |"HITOMI" |""で囲まれた部分を出力 | |―――――――――――+――――――――+――――――――――――――――| |#〈式1〉,〈式2〉 |#4,A |〈式1〉の スペースをとって | |          | |〈式2〉を右ずめ出力。 | ・―――――――――――――――――――――――――――――――――――――・                 コメント ・―――――――――――――――――――――――――――――――――――――・ |■■■一■般■形■■■|■使■用■例■■|■■■■機■■■■■■能■■■■| |―――――――――――+――――――――+――――――――――――――――| | (* *) | (*REMARK*) | 注 釈 | ・―――――――――――――――――――――――――――――――――――――・ *:追加予定                 演算子 ・―――――――――――――――――――――――――――――――――――――・ |■■■一■般■形■■■|■使■用■例■■|■■■■機■■■■■■能■■■■| |―――――――――――+――――――――+――――――――――――――――| | * |X=X2*3 | 乗算演算子 | |―――――――――――+――――――――+――――――――――――――――| | / |X=Y/3 | 除  〃 | |―――――――――――+――――――――+――――――――――――――――| | + |X=X+1 | 加  〃 | |―――――――――――+――――――――+――――――――――――――――| | - |X=X-1 | 減  〃 | |―――――――――――+――――――――+――――――――――――――――| | > |X>1  | 関係演算子 | |―――――――――――+――――――――|                | | >= |X>=1 | | |―――――――――――+――――――――|                | | < |X<1 | | |―――――――――――+――――――――|                | | <= |X<=1 | | |―――――――――――+――――――――|                | | = |X=1 | | |―――――――――――+――――――――|                | | <> |X<>1 | | |―――――――――――+――――――――+――――――――――――――――| | AND |X=1 AND X=2 | 論理演算子 | |―――――――――――+――――――――+――――――――――――――――| | OR |X=1 OR X=2 | | ・―――――――――――――――――――――――――――――――――――――・      優先順位は乗除、加減、関係、論理の順 (10)END文============= BASICにはシステムに戻るEND文 がありますが、 “K”にはEND文 はありません。 従ってシステムに戻るにはCALL命令を使うか、 スタックのレベルがもとに戻っていれば、 RETURN命令を使うことによリシステムに戻るようにします。 =−=−=−=−=−=−=−=−=−=   操作法(FM−8版) =−=−=−=−=−=−=−=−=−= (1)BASICのエディタを使って、   REM(注釈)文の形式で、“K”の文を作成します。   必要があれば,カセットまたはディスクヘSAVEをします。   一度SAVEしたものは、LOADして使えます。   作成する前に、    CLEAR10,&H1FFF[RET]   としておけば、コンパイラを壊すことかありません。              使用例1   ・――――――――――――――――――――・   |10 'PRINT"A=";A=INPUT;PRINT"B=";B=INPUT |   |20 'C=A+B;PRINT"A+B=",C,/        |   ・――――――――――――――――――――・ (2)BASICモードで、      EXEC&H2000[RET]   とします。   コンパイル・エラーを生じたときは、   エラーになった文を表示します。   (1)に戻って、エラーを修正します。             使用例2   ・――――――――――――――――――――・   | EXEC&H2000 |   | |   |  K-COMPILER V1 |   | |   | COPYRIGHT 1982 |   | |   | |   | COMPILING... |   | |   | |   | |   | OBJECT PROGRAM SIZE :54 ($0036) |   | |   | COMPILE END. |   | |   ・――――――――――――――――――――・ (3)コンパイルが正常に終り、オブジェクトが作成されたら、   BASICモードで、     EXEC&H4000[RET]   で実行します。   実行終了後は、BASICモードに戻ります。             使用例3   ・――――――――――――――――――――・   | EXEC&H4000 |   | A=10 |   | B=20 |   | A+B=30 |   |  |   | Ready |   ・――――――――――――――――――――・ (4)実行させるには、ランタイム・ルーチンが必要です。   生成されるオブジェクトは、完全にリロケータブルになっています。   実行中の変数エリアは、$6C00からの 256バイトが使われます。   K Compilerメモリ・マップ(FM-8版)   ・――――――――――――――――――――・   |  043D・―――――――・       |   |    |一行入力バッファ |       |   |  0CF3|―――――――|       |   |    |ソース・テキスト   |←$33,34の |   |  2000|―――――――|    内容 |   |    |コンパイラ    |       |   |  4000|―――――――|       |   |    |オブジェクト   |       |   |  5700|―――――――|       |   |    |コンパイラ・ワーク  |       |   |    |―――――――|       |   |    |スタック・エリア   |       |   |  6C00|―――――――|       |   |    |実行時変数エリア |       |   |  6D00|―――――――|       |   |    |ランタイム     |       |   |    |ルーチン     |       |   |  6FFF・―――――――・       |   ・――――――――――――――――――――・ =−=−=−=−=−=−=−=−=−=−   移植法(レベル3版) =−=−=−=−=−=−=−=−=−=− 下記のアドレスを変更すれば、レベル3で動きます。 ・―――――――――――――――――――――――――――・ |アドレス|内 容|      備    考      | |――――+―――+――――――――――――――――――| | $210B |A4  |実行終了時出ロアドレス       | | $2112 |38  |                  | |――――+―――+――――――――――――――――――| | $200E |A4  |コンパイル終了時出ロアドレス    | | $200F |38  |                  | |――――+―――+――――――――――――――――――| | $3DDC |1D  |テキスト・ポインタ・アドレス    | |――――+―――+――――――――――――――――――| | $6DE3 |02  |1行入力・バッファ・アドレス    | | $6DE4 |78  |                  | |――――+―――+――――――――――――――――――| | $6F80〜| リスト3 |入出力サブルーチン         | ・―――――――――――――――――――――――――――・ 操作法は、FM−8と同じですが、プログラム作成前に、    NEWON15[RET](80字モード)または、    NEWON11[RET](40字モード) を行なってください。 メモリ・マップは、FM−8版と同じです。 ■■■■■■■■■ランタイム・ルーチンL3版入出力部■■■■■■■■ ・―――――――――――――――――――――――――――――――――――――・ | NAM INOUT | | * INPUT FROM DISPLAY | |6F80 ORG $6F80 | |6F80 34 7D INEE PSHS CC,B,DP,X,Y,U | |6F82 86 00 LDA #$0 | |6F84 1F 8B TFR A,DP | |6F86 0F 9E CLR $9E | |6F88 BD E804 JSR $E804 | |6F8B 35 FD RET PULS CC,B,DP,X,Y,U,PC | | * OUTPUT TO DISPLAY | |6F9B ORG $6F9B | |6F9B 34 7F OUTEE PSHS CC,A,B,DP,X,Y,U | |6F9D C6 00 LDB #$0 | |6F9F 1F 9B TFR B,DP | |6FA1 0F 9E CLR $9E | |6FA3 BD E820 JSR $E820 | |6FA6 35 FF PULS CC,A,B,DP,X,Y,U,PC | | * INPUT LINE FROM DISPLAY | |6FB5 ORG $6FB5 | |6FB5 34 7F INLINE PSHS CC,A,B,DP,X,Y,U | |6FB7 86 00 LDA #$00 | |6FB9 1F 8B TFR A,DP | |6FBB BD DD50 JSR $DD50 | |6FBE 8E 0278 LDX #$0278 | |6FC1 A6 80 INLOOP LDA ,X+ | |6FC3 81 00 CMPA #$00 | |6FC5 26 FA 6FC1 BNE INLOOP | |6FC7 86 0D LDA #$0D | |6FC9 A7 82 STA ,-X | |6FCB 35 FF PULS CC,A,B,DP,X,Y,U,PC | | END | ・―――――――――――――――――――――――――――――――――――――・